package io.github.eric.urpc.example.test;

import io.github.eric.urpc.client.*;
import io.github.eric.urpc.core.conn.ConnectionListener;
import io.github.eric.urpc.core.exception.UrpcConnectException;
import io.github.eric.urpc.core.rpc.RpcContext;
import io.github.eric.urpc.core.rpc.RpcController;
import io.github.eric.urpc.core.rpc.RpcMethod;
import io.github.eric.urpc.example.msg.EchoMsg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collections;

public class MockClient {
    private static final Logger LOGGER = LoggerFactory.getLogger(MockClient.class);
    private Client client;

    private static ClientConfig.Builder getBuilder() {
        return new ClientConfig.Builder()
//                .nettyLoggingLevel(LogLevel.INFO)
                .applicationName("mockClient")
                .serverHost("127.0.0.1")
                .serverPort(52379)
                .ordered(true)
                // set controllers
                .rpcControllers(Collections.singletonList(new RpcController() {
                    @RpcMethod
                    public void onEchoMessage(RpcContext rpcContext, EchoMsg msg) {
                        LOGGER.info("Client receive a TestMessage, msg: {}, sendAt: {} from {}", msg.getMsg(), msg.getSendAt(), rpcContext.getRemoteAddress());
                    }
                }));
    }

    public MockClient(ConnectionListener... connectionListeners) {
        // init config
        ClientConfig clientConfig = getBuilder()
                .build();
        if (connectionListeners != null && connectionListeners.length > 0) {
            ((ClientContext)clientConfig).addConnectionListeners(Arrays.asList(connectionListeners));
        }

        // init client and connect to server
        client = new Client(clientConfig);
    }

    public void connectSync() {
        getClientConnector().connectSync();
    }

    public void connectAsync() {
        getClientConnector().connectAsync();
    }

    public ClientConnector getClientConnector() {
        ClientConnectionManager clientConnectionManager = ((ClientContext)client.getClientConfig()).getConnectionManager();
        try {
            Field field = clientConnectionManager.getClass().getDeclaredField("clientConnector");
            field.setAccessible(true);
            return (ClientConnector) field.get(clientConnectionManager);
        } catch (Exception e) {
            return null;
        }
    }

    public void shutdown() {
        client.shutdown();
    }

    public boolean isConnected() {
        return client.isConnected();
    }

    public Client getClient() {
        return client;
    }

    public static void main(String[] args) throws UrpcConnectException {
        MockClient simpleClient = new MockClient();
        simpleClient.connectSync();
    }
}
